/**
 *
 */
package commons.beancopier.internal;

import java.util.Map;


import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.ClassUtils;

import com.tmall.common.beancopier.AbstractPropertyCopier;
import com.tmall.common.beancopier.BeanCopier;
import com.tmall.common.beancopier.mapper.BeanMapperUtils;
import com.tmall.common.beancopier.mapper.PropertiesMapper;
import com.tmall.common.beancopier.mapper.PropertiesMapperBuilder;

/**
 * @author 陌铭(Phenix Huang)
 *
 */
public class TaobaoBeanPropertyCopier extends AbstractPropertyCopier {
    private static final String[] INCLUDE_LIST = new String[] {"com.taobao.", "com.alibaba.", "com.tmall."};



    public TaobaoBeanPropertyCopier() {
        super();
        // TODO Auto-generated constructor stub
    }

    public TaobaoBeanPropertyCopier(PropertiesMapperBuilder mapper, BeanCopier copier) {
        super(mapper, copier);
        // TODO Auto-generated constructor stub
    }

    /*
     * @see net.phenix.comp.util.beancopier.AbstractPropertyCopier#couldSmartCopy(java.lang.Class)
     */
    @Override
    public boolean couldSmartCopy(Class<?> propertyType) {
        String packageName = ClassUtils.getPackageName(propertyType);
        for (String prefix : INCLUDE_LIST) {
            if (packageName.startsWith(prefix)) {
                return true ;
            }
        }
        return false ;
    }

    /*
     * @see net.phenix.comp.util.beancopier.AbstractPropertyCopier#smartCopyProperty(java.lang.Object, java.lang.String, java.lang.Class, java.lang.Object)
     */
    @Override
    public void smartCopyProperty(Object dest, String propertyName, Class<?> propertyType, Object value)
            throws Exception {
        if (!PropertyUtils.isWriteable(dest, propertyName)) {
            return ;
        }
        Object to = null ;
        if (PropertyUtils.isReadable(dest, propertyName)) {
            to = PropertyUtils.getProperty(dest, propertyName);
        }
        if (to == null) {
            PropertiesMapper mapper = getPropertyMapper(propertyType);
            Map<String, String> propertyMap = BeanMapperUtils.getPropertyNameMap(propertyType);
            BeanMapperUtils.filterProperties(propertyMap, mapper);
            to = cloneAndFilterObject(dest, value, propertyType, propertyMap);
        } else {
            getBeanCopier().copyProperties(dest, to, value);
        }

        PropertyUtils.setProperty(dest, propertyName, to);
    }

}
